package view;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.GridLayout;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.Observable;
import java.util.Observer;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.plaf.basic.BasicComboPopup;
import javax.swing.plaf.basic.ComboPopup;
import javax.swing.plaf.metal.MetalComboBoxUI;

import model.CiiBay;

/**
 * De zoekbalk
 * @author Yasper & Nick & Jaap
 *
 */
@SuppressWarnings("serial")
public class Zoekpaneel extends JPanel implements Observer {
	private JLabel artikel, categorie, prijs;
	private JButton zoek;
	private JTextField artikelTekst, prijsTekst;
	private JComboBox categorieTekst;
	private CiiBay ciibay;

	public Zoekpaneel(CiiBay ciibay){
		new ArrayList<String>();
		this.ciibay=ciibay;
		setLayout(new GridLayout(1,7));
		artikel = new JLabel("Artikel:  ",JLabel.RIGHT);
		categorie = new JLabel("Categorie:  ",JLabel.RIGHT);
		prijs = new JLabel("Max. prijs:  ",JLabel.RIGHT);
		artikelTekst = new JTextField();
		artikelTekst.setDocument(new MaxAantalKarakters(250));
		artikelTekst.setText("");
		prijsTekst = new JTextField();
		prijsTekst.setDocument(new MaxAantalKarakters(10));
		prijsTekst.setText("0.00");
		categorieTekst = new JComboBox(ciibay.getCategories().toArray());
		categorieTekst.setUI(new MyComboBoxUI());
		categorieTekst.setMaximumRowCount(8);
		categorieTekst.setPreferredSize(new Dimension(110,30));
		zoek = new JButton("Zoek");
		zoek.addActionListener(new ZoekHandler());
		zoek.setBackground(Color.ORANGE);
		
		add(artikel);
		add(artikelTekst);
		add(categorie);
		add(categorieTekst);
		add(prijs);
		add(prijsTekst);
		add(zoek);
		this.setBackground(Color.ORANGE);

		artikelTekst.addKeyListener(new TekstKeyListener());
		prijsTekst.addKeyListener(new TekstKeyListener());
		categorieTekst.addKeyListener(new TekstKeyListener());

		ciibay.addObserver(this);
	}
	/**
	 * Zorgt ervoor dat als een admin een nieuwe categorie toevoegt deze ook in de zoekbalk zichtbaar is.
	 * @author Jaap
	 */
	@Override
	public void update(Observable o, Object arg) {
		String message = (String) arg;
		if(message.equals("nieuwecategorie")){
			categorieTekst.removeAllItems();
			for(Object obj : ciibay.getCategories().toArray()){
				categorieTekst.addItem(obj);
			}
			revalidate();
			repaint();
		}

	}

	class TekstKeyListener extends KeyAdapter {

		@SuppressWarnings("static-access")
		@Override
		public void keyPressed(KeyEvent arg0) {
			if(arg0.getKeyCode() == arg0.VK_ENTER){
				zoek.doClick();
			}
		}
	}

	class ZoekHandler implements ActionListener{
		/**
		 * De event handler voor de zoek knop. Controleert ook of de ingevulde prijs wel een getal is.
		 * @author Jaap
		 */
		@Override
		public void actionPerformed(ActionEvent arg0) {
			double tempPrijs = 0.00;
			boolean isGoed = false;
			if(!prijsTekst.getText().equals("")){
				try{
					tempPrijs = Double.parseDouble(prijsTekst.getText());
					if(tempPrijs >= 0){
						isGoed = true;
					}else{
						tempPrijs = Double.parseDouble("negatieve prijs");
					}
				}catch(NumberFormatException e){
					JOptionPane.showMessageDialog(null, "Ongeldige prijs!", "Melding",
							JOptionPane.WARNING_MESSAGE);
					ciibay.veranderView("welkom");
				}
			}else{
				JOptionPane.showMessageDialog(null, "Voer een maximum prijs in!", "Melding",
						JOptionPane.WARNING_MESSAGE);
				ciibay.veranderView("welkom");
			}
			if(isGoed)
			ciibay.zoekAdvertenties(artikelTekst.getText(), (String)categorieTekst.getSelectedItem(), tempPrijs);	
		}		
	}
	/**
	 * UI voor de combobox. Zorgt ervoor dat de popup breed genoeg is om de tekst volledig te zien.
	 * Combobox zelf blijft op z'n preferredsize staan en kapt te lange tekst af
	 * @see <a href="http://forums.sun.com/thread.jspa?messageID=10712893#10712893">Java forums</a>
	 * @author Jaap
	 *
	 */
	class MyComboBoxUI extends MetalComboBoxUI 
	{
		private int padding = 10;
		
		protected ComboPopup createPopup() 
		{
			BasicComboPopup popup = new BasicComboPopup( comboBox ) 
			{
				public void show() 
				{
					//Need to compute width of text
					int widest = getWidestItemWidth();
					
					//Get the box's size
					Dimension popupSize = comboBox.getSize();
					
					//Set the size of the popup
					popupSize.setSize( widest + ( 2 * padding ), getPopupHeightForRowCount( comboBox.getMaximumRowCount() ) );
					
					//Compute the complete bounds
					Rectangle popupBounds = computePopupBounds( 0, comboBox.getBounds().height, popupSize.width, popupSize.height );
					
					//Set the size of the scroll pane
					scroller.setMaximumSize( popupBounds.getSize() );
					scroller.setPreferredSize( popupBounds.getSize() );
					scroller.setMinimumSize( popupBounds.getSize() );
					
					//Cause it to re-layout
					list.invalidate();
					
					//Handle selection of proper item
					int selectedIndex = comboBox.getSelectedIndex();				
					if ( selectedIndex == -1 ) list.clearSelection();
					else list.setSelectedIndex( selectedIndex );
					
					//Make sure the selected item is visible
					list.ensureIndexIsVisible( list.getSelectedIndex() );
					
					//Use lightweight if asked for
					setLightWeightPopupEnabled( comboBox.isLightWeightPopupEnabled() );
					
					//Show the popup
					show( comboBox, popupBounds.x, popupBounds.y );
				}
			};
			
			popup.getAccessibleContext().setAccessibleParent( comboBox );
			
			return popup;
		}
		
		public int getWidestItemWidth()
		{
			//Items, font
			int numItems = comboBox.getItemCount();
			Font font = comboBox.getFont();
			FontMetrics metrics = comboBox.getFontMetrics( font );
			
			//The widest width
			int widest = 0;
			
			for ( int i = 0; i < numItems; i++ )
			{
				//Get the item
				Object item = comboBox.getItemAt( i );
				
				//Calculate the width of this line
				int lineWidth = metrics.stringWidth( item.toString() );
				
				//Use whatever's widest
				widest = Math.max( widest, lineWidth );
			}
			
			return widest;
		}
	}

}
